<template>
  <div class="calendar">
    <div class="weekdays weeks">
      <div v-for="day in weekdays" :key="day" class="week-item">
        <div class="cn">{{ day.cn }}</div>
        <div class="en">{{ day.en }}</div>
      </div>
    </div>
    <div class="weeks">
      <div v-for="(week, weekIndex) in weeksInMonth" :key="weekIndex" class="week">
        <div
          v-for="(day, dayIndex) in week"
          :key="dayIndex"
          class="day-item"
          :class="{
            'not-current': day === 0,
            'special-day': isSpecialDay(day),
            disabled: !canSelectDay(day, dayIndex)
          }"
          @click="selectDay(day, dayIndex)"
        >
          {{ day || '' }}
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, defineProps, defineEmits, onMounted } from 'vue'

const props = defineProps({
  specialDays: {
    type: Array as () => Array<{ start: number; end: number }>,
    default: () => []
  },
  selectedDate: String,
  displayMonth: {
    type: String,
    default: () => {
      const today = new Date()
      return `${today.getFullYear()}-${today.getMonth() + 1}`
    }
  }
})

const emit = defineEmits(['update:selectedDate'])

const weekdays = ref([
  { cn: '周日', en: 'Sun' },
  { cn: '周一', en: 'Mon' },
  { cn: '周二', en: 'Tue' },
  { cn: '周三', en: 'Wed' },
  { cn: '周四', en: 'Thu' },
  { cn: '周五', en: 'Fri' },
  { cn: '周六', en: 'Sat' }
])

const year = ref('')
const month = ref('')

const formattedDisplayMonth = computed(() => {
  return `${year.value}年${parseInt(month.value, 10) + 1}月`
})

const daysInMonth = computed(() => {
  const date = new Date(parseInt(year.value, 10), parseInt(month.value, 10) + 1, 0)
  return Array.from({ length: date.getDate() }, (_, i) => i + 1)
})

const firstDayOfMonth = computed(() => {
  const date = new Date(parseInt(year.value, 10), parseInt(month.value, 10), 1)
  return date.getDay()
})

const weeksInMonth = computed(() => {
  const days = daysInMonth.value
  const firstDay = firstDayOfMonth.value
  const weeks = []
  let week = []

  for (let i = 0; i < firstDay; i++) {
    week.push(0)
  }

  days.forEach((day) => {
    week.push(day)
    if (week.length === 7) {
      weeks.push(week)
      week = []
    }
  })

  if (week.length > 0) {
    while (week.length < 7) {
      week.push(0)
    }
    weeks.push(week)
  }

  return weeks
})

// 判断是否是可点击的日期（在 specialDays 的范围内）
const isSpecialDay = (day: number) => {
  if (!props.specialDays || props.specialDays.length === 0) return false

  for (const range of props.specialDays) {
    const { start, end } = range
    if (day >= start && day <= end) {
      return true
    }
  }

  return false
}

// 判断是否允许选择该日期
const canSelectDay = (day: number, dayIndex: number) => {
  if (day === 0) return false // 非本月不可选

  const date = new Date(parseInt(year.value), parseInt(month.value), day)
  const dayOfWeek = date.getDay()

  // 周一禁止选择，无论是否在 specialDays 中
  if (dayOfWeek === 1) return false

  // 其他日期只允许 specialDays 可选
  return isSpecialDay(day)
}

const selectDay = (day: number, dayIndex: number) => {
  if (canSelectDay(day, dayIndex)) {
    emit(
      'update:selectedDate',
      `${year.value}-${
        parseInt(month.value) >= 9 ? parseInt(month.value) + 1 : '0' + (parseInt(month.value) + 1)
      }-${day}`
    )
  }
}

const initDate = () => {
  const [getFullYear, getMonth] = props.displayMonth.split('-').map(Number)
  year.value = getFullYear.toString()
  month.value = (getMonth - 1).toString()

  // 不再自动选中今天，也不选中第一天
  if (!props.selectedDate) {
    emit('update:selectedDate', '')
  }
}

onMounted(() => {
  initDate()
})
</script>

<style scoped lang="scss">
.calendar {
  width: 670rpx;
  margin: 0 auto;
  text-align: center;
  padding-bottom: 10rpx;
}

.weekdays,
.weeks {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
}

.weekdays {
  margin-bottom: 30rpx;
  .week-item {
    width: 64rpx;
    margin-right: 34rpx;
    text-align: left;
    &:last-child {
      margin-right: 0;
    }
  }
}

.week {
  display: contents;
  .day-item {
    text-align: left;
    width: 64rpx;
    margin-bottom: 20rpx;
    margin-right: 34rpx;
    &:last-child {
      margin-right: 0;
    }
  }
}

.day-item {
  cursor: pointer;
}

.not-current {
  color: #ccc;
}

.special-day {
  color: #007aff;
  font-weight: bold;
}

.disabled {
  color: #ccc;
  pointer-events: none;
}
</style>
